package controllers;


import helper.AliyunOssUploader;
import helper.MyFFMPEGExecutableLocator;
import it.sauronsoftware.jave.AudioAttributes;
import it.sauronsoftware.jave.Encoder;
import it.sauronsoftware.jave.EncodingAttributes;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpConfigStorage;
import me.chanjar.weixin.mp.api.WxMpService;
import models.enums.VisitStatus;
import models.saleman.SaleManTask;
import models.saleman.SaleManTaskItem;
import models.weixin.WebUser;
import models.weixin.WxMpHelper;
import models.weixin.auth.UseJsApi;
import models.weixin.auth.WxMpAuthSaleMan;
import order.AdminOrder;
import org.apache.commons.lang.StringUtils;
import org.hibernate.SQLQuery;
import org.hibernate.transform.Transformers;
import play.Logger;
import play.Play;
import play.mvc.Controller;
import play.mvc.With;
import util.common.ConvertUtil;
import util.common.DateUtil;

import javax.persistence.Query;
import java.io.File;
import java.util.*;

@With(WxMpAuthSaleMan.class)
public class Application extends Controller {


    /**
     * 首页
     */
    public static void index() {

        WebUser webUser = WxMpAuthSaleMan.currentUser();
        String firstDayOfMonth = DateUtil.dateToString(DateUtil.firstDayOfMonth(), "yyyy-MM-dd");
        Date dayOfBegin = DateUtil.getBeginOfDay();
        String todayStr = DateUtil.dateToString(dayOfBegin, "yyyy-MM-dd");
        Date weekAgo = DateUtil.getBeforeDate(dayOfBegin, 7);

        List<Map<String, Object>> indexList = new ArrayList<>();
        double monthOrderAmount = 0.00; // 月 订单总额
        double monthPoportions = 0.00; // 月 总提成
        double weekOrderAmount = 0.00; // 近7天订单总额
        double weekPoportions = 0.00; //  近7填提成总额
        double dayOrderAmount = 0.00; //   当日订单总额
        double dayPoportions = 0.00; //    当日总提成


        String sqlSelect = "  select * from (select a.id   " +
                "    ,a.web_user_id  " +
                "    , a.`code`   " +
                "    , a.amount   " +
                "    , a.created_at  " +
                "    , sum(ifnull(b.sale_price ,0)* ifnull(b.buy_number ,0) * ifnull(e.poportions ,0)/100) as order_poportions   " +
                "    from admin_order a   " +
                "    left join admin_order_item b on a.id = b.admin_order and b.deleted = 0   " +
                "    left join goods c on b.goods_id = c.id   " +
                "    left join product_spec_merchants d on c.serial_id = d.id  " +
                "    left join product_specs e on d.product_spec_id = e.id   " +
                "    where a.deleted = 0 and a.to_track = 1  and a.create_at > '%s' and a.sale_man_user_id = %d  " +
                "    group by a.id  ) a  " +
                "  left join (  " +
                "  select a.web_user_id , max(a.user_name) as user_name from address a where a.deleted = 0 and a.is_default = 1 group by a.web_user_id  " +
                "  ) b  on a.web_user_id = b.web_user_id ;  ";

        String sqlData = String.format(sqlSelect, firstDayOfMonth, webUser.id);

        Query query = AdminOrder.em().createNativeQuery(sqlData);
        query.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        List<Map<String, Object>> dataList = query.getResultList();
        if (dataList != null && dataList.size() > 0) {
            for (Map<String, Object> data : dataList) {

                monthOrderAmount += ConvertUtil.toDouble(data.get("amount"));
                monthPoportions += ConvertUtil.toDouble(data.get("order_poportions"));

                Date orderDate = DateUtil.stringToDate(ConvertUtil.toString(data.get("created_at")), "yyyy-MM-dd");
                String orderDateStr = DateUtil.dateToString(orderDate, "yyyy-MM-dd");
                //周 订单金额 和提成
                if (orderDate.after(weekAgo)) {
                    weekOrderAmount += ConvertUtil.toDouble(data.get("amount"));
                    weekPoportions += ConvertUtil.toDouble(data.get("order_poportions"));
                }
                //当日订单金额和提成
                if (todayStr.equals(orderDateStr)) {
                    dayOrderAmount += ConvertUtil.toDouble(data.get("amount"));
                    dayPoportions += ConvertUtil.toDouble(data.get("order_poportions"));
                    if (indexList.size() <= 5) indexList.add(data);
                }

            }
        }

        render(webUser, indexList, monthOrderAmount, monthPoportions, weekOrderAmount, weekPoportions, dayOrderAmount, dayPoportions);
    }

    public static void currentDateOrderList(){
        render();
    }

    //当日订单列表页
    public static void loadOrderList( Integer pageNum , Integer pageSize){
        Map<String  , Object> resultMap = new HashMap<>();

        pageNum = pageNum == null || pageNum == 0 ? 1 : pageNum ;
        pageSize = pageSize == null || pageSize == 0 ? 5 : pageSize ;
        WebUser webUser = WxMpAuthSaleMan.currentUser();

        if(webUser == null){
            resultMap.put("success" , false);
            resultMap.put("msg" , "业务员信息获取失败！");
            renderJSON(resultMap);
        }
        List<Map<String , Object>> dataList = new ArrayList<>(); //存放所有数据的集合
        Map<Long , Map<String ,Object>> orderMap = new HashMap<>(); // 存放adminOrder 的Map
        Map<Long ,List<Map<String ,Object>>> orderItemMap = new HashMap<>(); // 存放adminOrderItem的Map
        String sqlSelect = "   select a.id , " +
                "    a.order_no , " +
                "    date_format(a.create_at , '%%Y-%%m-%%d %%H:%%i:%%s') as order_at , " +
                "    a.user_name , " +
                "    a.confirm_address ,  " +
                "    f.`name` as goods_name ,   " +
                "    e.spec as goods_spec ,   " +
                "    e.unit as goods_unit ,   " +
                "    e.main_image as pro_image ,   " +
                "    a.amount ,  " +
                "    b.buy_number ,  " +
                "    b.sale_price ,  " +
                "    ifnull(b.sale_price,0)*ifnull(b.buy_number,0) as goods_amount ,  " +
                "    ifnull(e.poportions,0) as poportions ,   " +
                "    round(ifnull(e.poportions,0) * ifnull(b.sale_price,0)*ifnull(b.buy_number,0)/100 , 2) as poportions_amount    " +
                "    from (  " +
                "      select a.id ,   " +
                "      a.order_no ,   " +
                "      a.amount ,   " +
                "      a.create_at ,   " +
                "      b.user_name ,   " +
                "      b.confirm_address     " +
                "      from admin_order a   " +
                "      left join address b on a.address_id = b.id    " +
                "      where a.deleted = 0 and a.to_track = 1 and a.sale_man_user_id = %d and a.create_at >= CURRENT_DATE()   %s " +
                "      )a  " +
                "    left join admin_order_item b on a.id = b.admin_order  " +
                "    left join goods c on b.goods_id = c.id and c.deleted = 0  " +
                "    left join product_spec_merchants d on c.serial_id = d.id   " +
                "    left join product_specs e on d.product_spec_id  = e.id  " +
                "    left join products f on e.product_id = f.id    " +
                "    order by a.id ;" ;


        String sqlData = String.format(sqlSelect , ConvertUtil.toLong(webUser.id ), " limit "+(pageNum -1)* pageSize +" , " + pageSize) ;
        Query query = AdminOrder.em().createNativeQuery(sqlData);
        query.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        List<Map<String , Object>> resultList = query.getResultList();

        if(resultList == null || resultList.size() > 0){
            for(Map<String , Object> map : resultList){
                long orderId = ConvertUtil.toLong(map.get("id"));
                if(orderMap.get(orderId) == null){  // 如果订单信息不存在 ， 则放入订单信息
                    Map<String , Object> adminOrder = new HashMap<>();
                    adminOrder.put("order_id",orderId);
                    adminOrder.put("amount",map.get("amount"));
                    adminOrder.put("user_name",map.get("user_name"));
                    adminOrder.put("confirm_address",map.get("confirm_address"));
                    adminOrder.put("order_no",map.get("order_no"));
                    adminOrder.put("order_at",map.get("order_at"));
                    adminOrder.put("poportions_amount",map.get("poportions_amount"));
                    List<Map<String , Object>> orderItem = new ArrayList<>();
                    Map<String, Object> itemMap = new HashMap<>();
                    itemMap.put("goods_name",map.get("goods_name"));
                    itemMap.put("goods_spec",map.get("goods_spec"));
                    itemMap.put("goods_unit",map.get("goods_unit"));
                    itemMap.put("pro_image",map.get("pro_image"));
                    itemMap.put("buy_number",map.get("buy_number"));
                    itemMap.put("sale_price",map.get("sale_price"));
                    itemMap.put("goods_amount",map.get("goods_amount"));
                    itemMap.put("poportions",map.get("poportions"));
                    itemMap.put("poportions_amount",map.get("poportions_amount"));
                    orderItem.add(itemMap);
                    orderItemMap.put(orderId,orderItem);
                    adminOrder.put("orderItem" , orderItemMap.get(orderId));
                    orderMap.put(orderId , adminOrder);
                    dataList.add(orderMap.get(orderId));
                }else { //如果不为空 已存在，则放入 订单明细item 商品 信息
                    Map<String, Object> itemMap = new HashMap<>();
                    itemMap.put("goods_name",map.get("goods_name"));
                    itemMap.put("goods_spec",map.get("goods_spec"));
                    itemMap.put("goods_unit",map.get("goods_unit"));
                    itemMap.put("pro_image",map.get("pro_image"));
                    itemMap.put("buy_number",map.get("buy_number"));
                    itemMap.put("sale_price",map.get("sale_price"));
                    itemMap.put("goods_amount",map.get("goods_amount"));
                    itemMap.put("poportions",map.get("poportions"));
                    itemMap.put("poportions_amount",map.get("poportions_amount"));

                    orderItemMap.get(orderId).add(itemMap);
                    //统计提成金额
                    double total_poportions_amount = ConvertUtil.toDouble(orderMap.get(orderId).get("poportions_amount")) + ConvertUtil.toDouble(map.get("poportions_amount")) ;
                    orderMap.get(orderId).put("poportions_amount" , total_poportions_amount) ;

                }
            }
        }



        resultMap.put("success" , true);
        resultMap.put("orderList" , dataList);
        renderJSON(resultMap);


    }

    // 当日任务列表
    public static void currentTaskItem(Long id) {
        WebUser webUser = WxMpAuthSaleMan.currentUser();
        Date today = DateUtil.getBeginOfDay();
        SaleManTask saleManTask;
        int isToday = 0 ;
        if (id == null || id == 0) {
            saleManTask = SaleManTask.findBySaleManAndTaskDate(webUser.id, today);

        } else {
            saleManTask = SaleManTask.findByTaskId(id);
            isToday = 1 ;
        }

        if(saleManTask != null && DateUtil.dateToString(new Date(),"yyyy-MM-dd").equals(DateUtil.dateToString(saleManTask.taskDate , "yyyy-MM-dd")))
            isToday = 0 ;

        List<SaleManTaskItem> taskItemList = new ArrayList<>();
        if (saleManTask != null) {
            taskItemList = SaleManTaskItem.loadByTaskId(saleManTask.id);
        }

        render(saleManTask, taskItemList , isToday);
    }


    //         开始录音接口     停止录音        上传语音接口     获取位置接口     识别音频
    @UseJsApi({"startRecord", "stopRecord", "uploadVoice", "getLocation" , "translateVoice"})
    public static void taskRecord(Long id) {
        WebUser webUser = WxMpAuthSaleMan.currentUser();
        SaleManTaskItem taskRecord ;
        if( id == null || id == 0 ){
            taskRecord = SaleManTaskItem.findByUserAndStatus(webUser, VisitStatus.ON_GOING);
            if(taskRecord == null)
                taskRecord = SaleManTaskItem.findByUser(webUser);
        }else {
            taskRecord = SaleManTaskItem.findByItemId(id);
        }
        if(taskRecord == null)
            redirect("/task/history");
        render(taskRecord , id);
    }


    //保存录音
    public static void saveVoice( long id ,String paramName , String voiceServerId , String voiceContent  , String latitude , String longitude) throws WxErrorException {
       Map<String , Object> resultMap = new HashMap<>();
        SaleManTaskItem saleManTaskItem = SaleManTaskItem.findByItemId(id);
        if(saleManTaskItem == null){
            resultMap.put("success",false);
            resultMap.put("msg","拜访任务信息获取失败，无法保存！");
            renderJSON(resultMap);
        }

        if(StringUtils.isBlank(paramName) || StringUtils.isBlank(voiceServerId)){
            resultMap.put("success",false);
            resultMap.put("msg","语音信息为空 ，保存失败！");
            renderJSON(resultMap);
        }
        WxMpConfigStorage wxMpConfigStorage = WxMpHelper.getWxMpConfigStorage();
        WxMpService wxMpService = WxMpHelper.getWxMpService(wxMpConfigStorage);

        String path = "public/images/upload/";

        File mediaFile  = wxMpService.mediaDownload(voiceServerId);
        //建立mp3
        String mp3FileName = mediaFile.getName().replaceAll("\\.amr", "\\.mp3");
        Encoder encoder = new Encoder(new MyFFMPEGExecutableLocator());
        AudioAttributes audio = new AudioAttributes();
        File targetMp3File = Play.getFile(path + mp3FileName);

        audio.setCodec("libmp3lame");
        EncodingAttributes attrs = new EncodingAttributes();
        attrs.setFormat("mp3");
        attrs.setAudioAttributes(audio);
        try {
            encoder.encode(mediaFile, targetMp3File, attrs);
        } catch (Exception e) {
            Logger.warn(e, "encoder.encode fail");
        }

        //将语音文件保存到阿里云
        String voiceFile = AliyunOssUploader.uploadPublicFile(mediaFile);
        //保存签到语音，保存获取到的签到地址，并将任务状态改为进行中
        if(paramName.equals("signVoice")){
            saleManTaskItem.signVoice = voiceFile ;
            saleManTaskItem.signContent = voiceContent ;
            saleManTaskItem.signAt = new Date();
            saleManTaskItem.save();
        }

        //保存拜访目的语音
        if(paramName.equals("targetVoice")){
            saleManTaskItem.targetVoice = voiceFile ;
            saleManTaskItem.targetContent = voiceContent ;
            saleManTaskItem.latitude = latitude ;
            saleManTaskItem.longitude = longitude ;
            saleManTaskItem.save();
        }

          //保存问题语音
        if(paramName.equals("problemVoice")){
            saleManTaskItem.problemVoice = voiceFile ;
            saleManTaskItem.existingProblems = voiceContent ;
            saleManTaskItem.save();
        }

           //保存分析语音，并将状态改为结束
        if(paramName.equals("analysisVoice")){
            saleManTaskItem.analysisVoice = voiceFile ;
            saleManTaskItem.analysisProblems = voiceContent ;
            saleManTaskItem.visitStatus = VisitStatus.END;
            saleManTaskItem.save();

        }

        resultMap.put("success",true);
        resultMap.put("id",id);
        renderJSON(resultMap);

    }


    //历史任务
    public static void historyTasks() {
        render();
    }

    public static void getHistoryTasks(Integer pageNum, Integer pageSize, String beganAt, String endAt) {
        Map<String, Object> resultMap = new HashMap<>();
        WebUser webUser = WxMpAuthSaleMan.currentUser();
        if (webUser == null) {
            resultMap.put("success", false);
            resultMap.put("msg", "登录用户信息获取失败，无法查询！");
            renderJSON(resultMap);
        }

        pageNum = pageNum == null ? 1 : pageNum;
        int taskIndex = (pageNum - 1) * pageSize;

        String sqlSelect = "select a.id , DATE_FORMAT(a.task_date,'%%Y-%%m-%%d') as task_date   from sale_man_tasks a   " +
                "  left join give_web_user_auths b on a.sale_man_id = b.id and b.deleted = 0   " +
                "  where b.web_user_id = %d and a.deleted = 0 %s" +
                "    order by a.task_date desc   " +
                "   %s ";

        String sqlWhere = "";


        if (StringUtils.isNotBlank(beganAt))
            sqlWhere += " and a.task_date >= '" + beganAt + "'";

        if (StringUtils.isNotBlank(endAt))
            sqlWhere += " and a.task_date <= '" + endAt + "'";

        String sqlData = String.format(sqlSelect, webUser.id, sqlWhere, "limit " + (pageNum - 1) * pageSize + "," + pageSize);

        Query query = SaleManTask.em().createNativeQuery(sqlData);
        query.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        List<Map<String, Object>> dataList = query.getResultList();
        if (dataList != null && dataList.size() > 0) {
            for (Map<String, Object> map : dataList) {
                taskIndex++;
                map.put("task_index", taskIndex);
            }
        }

        resultMap.put("success", true);
        resultMap.put("taskList", dataList);
        renderJSON(resultMap);
    }
}
